package main

import (
	"fmt"
	"io"
	"strings"
)

// fp vs pointer
// fp: function is the first citizen
// closure
// function programing
// 高阶函数
func adder() func(int) int {
	value := 0
	return func(v int) int {
		value += v
		return value
	}
}

// no state
// no variable
// single param
// 尝试纯函数式编程
type iAdder func(int) (int, iAdder)

func adder2(base int) iAdder {
	return func(v int) (int, iAdder) {
		return base + v, adder2(base + v)
	}
}

// 闭包
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b, a+b
		return a
	}
}

// IntGen 重新认识一等公民 => 类型, 参数, 变量, 返回值, 定义方法
type IntGen func() int //

func (g IntGen) Read(p []byte) (n int, err error) {
	val := g()
	if val > 10000 {
		return -1, io.EOF
	}
	s := fmt.Sprintf("%d\n", val)
	return strings.NewReader(s).Read(p)
}

// entry
func main() {
	f := adder2(0)
	var s int
	for i := 0; i <= 10; i++ {
		// iterator value
		s, f = f(i)
		fmt.Printf("0 + 1 + 2 + ... + %d = %d\n",
			i, s)
	}

	fib := fibonacci()
	fmt.Println(
		fib(),
		fib(),
		fib(),
		fib(),
		fib(),
		fib(),
		fib(),
		fib(),
		fib(),
	)
}
